package cn.stylefeng.guns.modular.business.app.controller.file;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.URLUtil;
import cn.stylefeng.guns.annotation.AnonymousGetMapping;
import cn.stylefeng.guns.config.AliyunOSSConfig;
import cn.stylefeng.guns.core.context.login.LoginContextHolder;
import cn.stylefeng.guns.core.enums.ReturnCode;
import cn.stylefeng.guns.core.exception.CustomException;
import cn.stylefeng.guns.core.pojo.response.ResponseData;
import cn.stylefeng.guns.modular.business.app.controller.vo.DownloadData;
import cn.stylefeng.guns.modular.business.frequency.cmcity.mapper.CmCityMapper;
import cn.stylefeng.guns.modular.business.frequency.ordercarverify.mapper.OrderCarVerifyMapper;
import cn.stylefeng.guns.modular.business.frequency.orderfinish.model.param.FinishRecordContractVO;
import cn.stylefeng.guns.modular.business.frequency.orderfinish.service.OrderFinishService;
import cn.stylefeng.guns.modular.business.frequency.orderfinishrecord.mapper.OrderFinishRecordMapper;
import cn.stylefeng.guns.modular.business.frequency.orderpick.model.param.OrderContractVO;
import cn.stylefeng.guns.modular.business.frequency.orderpick.model.param.PickRecordContractVO;
import cn.stylefeng.guns.modular.business.frequency.orderpick.model.param.TakeRecordContractVO;
import cn.stylefeng.guns.modular.business.frequency.orderpick.model.result.PkgOrderPick;
import cn.stylefeng.guns.modular.business.frequency.orderpick.service.OrderPickService;
import cn.stylefeng.guns.modular.business.frequency.ordersub.entity.OrderSub;
import cn.stylefeng.guns.modular.business.frequency.ordersub.model.param.OrderVO;
import cn.stylefeng.guns.modular.business.frequency.ordersub.model.result.PkgOrderSub;
import cn.stylefeng.guns.modular.business.frequency.ordersub.service.OrderSubService;
import cn.stylefeng.guns.modular.business.frequency.ordertake.model.result.PkgOrderDelivery;
import cn.stylefeng.guns.modular.business.frequency.ordertake.service.OrderTakeService;
import cn.stylefeng.guns.modular.business.frequency.transport.model.result.PkgTransport;
import cn.stylefeng.guns.modular.business.frequency.transportlevel.mapper.TransportLevelMapper;
import cn.stylefeng.guns.modular.business.frequency.transportleveldetail.entity.TransportLevelDetail;
import cn.stylefeng.guns.modular.business.util.BusinessUtil;
import cn.stylefeng.guns.modular.util.EasyExcelUtil;
import cn.stylefeng.guns.modular.util.itext.ItextUtil;
import cn.stylefeng.guns.modular.util.oss.StsService;
import cn.stylefeng.guns.modular.util.oss.UploadFile2OSS;
import cn.stylefeng.guns.sys.modular.util.SnowIdUtils;
import com.aliyuncs.sts.model.v20150401.AssumeRoleResponse;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Description:
 * @Author jzy
 * @Date 2020/10/9 0009
 **/
@Slf4j
@RestController
@RequestMapping("/api/file")
public class FileController {

    @Value("${tuotuo.contract.path}")
    private String contractPath;
    //@Value("${tuotuo.validate.short-url}")
    //private String shareValidateShortUrl;
    @Value("${tuotuo.contract.logo.img}")
    private String contractLogoImg;
    //@Value("${tuotuo.contract.sign.img}")
    //private String contractSignImg;

    @Value("${tuotuo.insurance.logo.img}")
    private String insuranceLogoImg;
    @Value("${tuotuo.insurance.sign.img}")
    private String insuranceSignImg;
    @Value("${tuotuo.insurance.water.img}")
    private String insuranceWaterImg;

    @Value("${tuo.transport.cardNumber.img}")
    private String transportCardNumberImg;

    @Resource
    private OrderSubService orderSubService;

    @Resource
    private CmCityMapper cmCityMapper;
    @Resource
    private TransportLevelMapper transportLevelMapper;
    @Resource
    private StsService stsService;
    @Resource
    private OrderCarVerifyMapper orderCarVerifyMapper;

    @Resource
    private OrderFinishRecordMapper orderFinishRecordMapper;
    @Resource
    private OrderFinishService finishService;

    @Resource
    private BusinessUtil businessUtil;

    @Resource
    private AliyunOSSConfig aliyunOSSConfig;

    @GetMapping("/sts-token")
    public ResponseData getOSSToken() {
        AssumeRoleResponse response = stsService.assumeRole(
                aliyunOSSConfig.getRegionId(),
                aliyunOSSConfig.getAccessKeyId(),
                aliyunOSSConfig.getAccessKeySecret(),
                aliyunOSSConfig.getAscArm(),
                "session", null, 3600L);
        if (response != null) {
            return ResponseData.andaSuccess(ReturnCode.RETURN_SUCCESS.code, response.getCredentials(), "OssToken获取成功");
        }
        return ResponseData.andaError(ReturnCode.RETURN_ERROR.code, "OssToken获取失败");
    }

    @ApiOperation(value = "生成合同")
    @PostMapping("/contract")
    public ResponseData getContract(@RequestBody String[] ids) {
        List<Long> idList = Arrays.stream(ids)
                .map(Long::parseLong)
                .collect(Collectors.toList());

        OrderVO order = orderSubService.getOrderVOByOrderIdList(idList);
        // 是否含保险
        if (order.getOrderSubList().stream().map(OrderSub::getHasInsurance).distinct().count() > 1) {
            return ResponseData.andaError("所选订单同时包含有保险、无保险的车辆，不可同时生成！");
        }
        String result = "";
        String fileName = order.getLinkmanName() + "-" + DateUtil.format(new Date(), "yyyyMMddHHmmss");
        String contractSignImg = businessUtil.getContractSignImg();
        if (StringUtils.isBlank(contractSignImg)) {
            throw new CustomException("签章文件不存在，请先上传签章文件！");
        }

        try {
            order.setStartCode(cmCityMapper.getNameByCode(order.getStartCode()));
            order.setDestinationCode(cmCityMapper.getNameByCode(order.getDestinationCode()));
            ItextUtil.createConcatPDF(order, contractPath, fileName,
                    getClass().getResource(contractLogoImg),
                    /*todo 修改成网络图片 读取租户的签章图片地址*/
                    //getClass().getResource(contractSignImg),
                    URLUtil.url(contractSignImg),
                    businessUtil.getTenantCompanyName());
            //上传文件至阿里云
            File fileTemp = new File(contractPath + fileName + ".pdf");
            InputStream in = new FileInputStream(fileTemp);
            UploadFile2OSS oss = new UploadFile2OSS(aliyunOSSConfig);
            result = "http://tuotuo-dev.oss-cn-beijing.aliyuncs.com/" + fileName + ".pdf";
            oss.uploadPublic(aliyunOSSConfig.getBucketName(), fileName + ".pdf", in);
            oss.closeConnect();
            in.close();
            //删除本地文件
            if (fileTemp.exists()) {
                fileTemp.delete();
            }
        } catch (IOException e) {
            e.printStackTrace();
            return ResponseData.andaError(ReturnCode.RETURN_ERROR.code, "生成合同失败");
        }
        return ResponseData.andaSuccess(ReturnCode.RETURN_SUCCESS, result, "合同生成成功");
    }

    @ApiOperation(value = "生成保单")
    @PostMapping("/insurance")
    public ResponseData getInsurance(@RequestBody String[] ids) {
        List<Long> idList = Arrays.asList(ids).stream().map(it -> Long.valueOf(it)).collect(Collectors.toList());

        OrderVO order = orderSubService.getOrderVOByOrderIdList(idList);
        String result = "";
        try {
            //生成本地合同
            order.setStartCode(cmCityMapper.getNameByCode(order.getStartCode()));
            order.setDestinationCode(cmCityMapper.getNameByCode(order.getDestinationCode()));
            ItextUtil.createPDFInsurance(order,businessUtil.getTenantCompanyName(), contractPath, getClass().getResource(insuranceLogoImg),  getClass().getResource(insuranceSignImg), getClass().getResource(insuranceWaterImg));
            //上传文件至阿里云
            File fileTemp = new File(contractPath + "保单-" + order.getLinkmanName() + ".pdf");
            InputStream in = new FileInputStream(fileTemp);
            UploadFile2OSS oss = new UploadFile2OSS(aliyunOSSConfig);
            result = "http://tuotuo-dev.oss-cn-beijing.aliyuncs.com/" + "保单-" + order.getLinkmanName() + ".pdf";
            oss.uploadPublic(aliyunOSSConfig.getBucketName(), "保单-" + order.getLinkmanName() + ".pdf", in);
            oss.closeConnect();
            in.close();
            //删除本地文件
            if (fileTemp.exists()) {
                fileTemp.delete();
            }
        } catch (IOException e) {
            e.printStackTrace();
            return ResponseData.andaError(ReturnCode.RETURN_ERROR.code, "生成保单失败");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return ResponseData.andaSuccess(ReturnCode.RETURN_SUCCESS, result, "保单生成成功");
    }

    @ApiOperation(value = "运单分段信息生成")
    @PostMapping("/transport-level")
    public ResponseData getTransportLevel(@RequestBody OrderContractVO orderContractVO) {
        PkgTransport transport = transportLevelMapper.getPkgTransportByLevelId(orderContractVO.getTransportLevelId());
        for (TransportLevelDetail tld : transport.getTransportLevelList().get(0).getTransportLevelDetailList()) {
            // 验车信息
            tld.setOrderCarVerify(orderCarVerifyMapper.getPkgOrderCarVerify(tld.getOrderId()));
        }
        String result = "";
        try {
            //生成本地合同
            Map<String, Object> map = new HashMap<>();
            map.put("startCityName", cmCityMapper.getNameByCode(transport.getTransportLevelList().get(0)
                    .getTransportLevelDetailList().get(0).getStartCode()));
            map.put("destinationCityName", cmCityMapper.getNameByCode(transport.getTransportLevelList().get(0)
                    .getTransportLevelDetailList().get(0).getDestinationCode()));
            String pdfName = "level_" + orderContractVO.getTransportLevelId() + ".pdf";
            map.put("fileName",pdfName);

            ItextUtil.createPDFTransportLevel(transport, map, contractPath, getClass().getResource(transportCardNumberImg), businessUtil.getTenantCompanyName());
            //上传文件至阿里云
            File fileTemp = new File(contractPath + pdfName);
            InputStream in = new FileInputStream(fileTemp);
            UploadFile2OSS oss = new UploadFile2OSS(aliyunOSSConfig);
            result = "http://tuotuo-dev.oss-cn-beijing.aliyuncs.com/" + pdfName;
            oss.uploadPublic(aliyunOSSConfig.getBucketName(), pdfName, in);
            oss.closeConnect();
            in.close();
            //删除本地文件
            if (fileTemp.exists()) {
                fileTemp.delete();
            }
            //保存返回地址入库
//            if (!orderContractVO.isRetry()) {
            // 更新文件地址
            transportLevelMapper.updateFileUrl(orderContractVO.getTransportLevelId(), result);
//            }
        } catch (IOException e) {
            e.printStackTrace();
            log.error("生成分段运单失败", e);
            return ResponseData.andaError(ReturnCode.RETURN_ERROR.code, "生成分段运单失败");
        } catch (Exception e) {
            e.printStackTrace();
            log.error("生成分段运单失败", e);
        }
        return ResponseData.andaSuccess(ReturnCode.RETURN_SUCCESS, result, "运单分段信息生成成功");
    }

    @ApiOperation(value = "交付单生成")
    @PostMapping("/finish-record-contract")
    public ResponseData getFinishRecordContract(@RequestBody FinishRecordContractVO finishRecordContractVO) {
        List<PkgOrderSub> orderSubList = finishService.getPkgOrderFinishRecordDetail(finishRecordContractVO);
        String result = "";
        try {
            Map<String, Object> map = new HashMap<>();
            String fileName = StringUtils.isBlank(finishRecordContractVO.getFinishRecordId()) ? SnowIdUtils.uniqueLongHex() : finishRecordContractVO.getFinishRecordId();
            map.put("startCityName", cmCityMapper.getNameByCode(orderSubList.get(0).getStartCode()));
            map.put("destinationCityName", cmCityMapper.getNameByCode(orderSubList.get(0).getDestinationCode()));
            map.put("fileName", fileName);
            String name = contractPath + "level_" + fileName + ".pdf";
            ItextUtil.createPDFOrderFinishRecord(orderSubList, map, businessUtil.getTenantCompanyName(), name);
            //上传文件至阿里云
            File fileTemp = new File(name);
            InputStream in = new FileInputStream(fileTemp);
            UploadFile2OSS oss = new UploadFile2OSS(aliyunOSSConfig);
            result = "http://tuotuo-dev.oss-cn-beijing.aliyuncs.com/finish-record/" + "level_" + fileName + ".pdf";
            oss.uploadPublic(aliyunOSSConfig.getBucketName(), "finish-record/" + "level_" + fileName + ".pdf", in);
            oss.closeConnect();
            in.close();
            //删除本地文件
            if (fileTemp.exists()) {
                fileTemp.delete();
            }
            //保存返回地址入库
            if (StringUtils.isNotBlank(finishRecordContractVO.getFinishRecordId())) {
                //OrderFinishRecord frc = new OrderFinishRecord();
                //frc.setId(Long.valueOf(finishRecordContractVO.getFinishRecordId()));
                //frc.setContractPath(result);
                //orderFinishRecordMapper.insert(frc);
                orderFinishRecordMapper.updatePathById(finishRecordContractVO.getFinishRecordId(), result);
            }
        } catch (IOException e) {
            e.printStackTrace();
            return ResponseData.andaError(ReturnCode.RETURN_ERROR.code, "交付单生成失败");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return ResponseData.andaSuccess(ReturnCode.RETURN_SUCCESS, result, "交付单生成成功");
    }

    @Resource
    private OrderPickService pickCarService;

    @ApiOperation(value = "提车单生成")
    @PostMapping("/pick-record-contract")
    public ResponseData billOfLadingGeneration(@RequestBody PickRecordContractVO pickRecordContractVO) {

        PkgOrderPick pkgOrderPick = pickCarService.billOfLadingGeneration(pickRecordContractVO);
        String result = "";
        try {
            Map<String, Object> map = new HashMap<>();
            String fileName = StringUtils.isBlank(pickRecordContractVO.getId()) ? SnowIdUtils.uniqueLongHex() : pickRecordContractVO.getId();
            map.put("startCityName", cmCityMapper.getNameByCode(pkgOrderPick.getStartCode()));
            map.put("destinationCityName", cmCityMapper.getNameByCode(pkgOrderPick.getDestinationCode()));
            String name = contractPath + "level_" + fileName + ".pdf";
            // TODO: 2023/6/26 创建提车单PDF
            ItextUtil.createPDFBillOfLadingRecord(pkgOrderPick, map, businessUtil.getTenantCompanyName(), name);
            //上传文件至阿里云
            File fileTemp = new File(name);
            InputStream in = new FileInputStream(fileTemp);
            UploadFile2OSS oss = new UploadFile2OSS(aliyunOSSConfig);
            result = "http://tuotuo-dev.oss-cn-beijing.aliyuncs.com/bill-record/" + "level_" + fileName + ".pdf";
            oss.uploadPublic(aliyunOSSConfig.getBucketName(), "bill-record/" + "level_" + fileName + ".pdf", in);
            oss.closeConnect();
            in.close();

            //删除本地文件
            if (fileTemp.exists()) {
                fileTemp.delete();
            }
        } catch (IOException e) {
            e.printStackTrace();
            return ResponseData.andaError(ReturnCode.RETURN_ERROR.code, "提车单生成失败");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return ResponseData.andaSuccess(ReturnCode.RETURN_SUCCESS, result, "提车单生成成功");
    }


    @Resource
    private OrderTakeService orderTakeService;

    @ApiOperation(value = "送车单生成")
    @PostMapping("/tack-record-contract")
    public ResponseData dropOffTheCarGeneration(@RequestBody TakeRecordContractVO takeRecordContractVO) {
        List<PkgOrderDelivery> orderSubList = orderTakeService.getWaitTakeCarOrderList(takeRecordContractVO);
        String result = "";
        try {
            Map<String, Object> map = new HashMap<>();
            String fileName = StringUtils.isBlank(takeRecordContractVO.getFinishRecordId()) ? SnowIdUtils.uniqueLongHex() : takeRecordContractVO.getFinishRecordId();
            map.put("startCityName", cmCityMapper.getNameByCode(orderSubList.get(0).getStartCode()));
            map.put("destinationCityName", cmCityMapper.getNameByCode(orderSubList.get(0).getDestinationCode()));
            map.put("fileName", fileName);
            String name = contractPath + "level_" + fileName + ".pdf";
            ItextUtil.createPDFVehicleDeliverySlipGeneration(orderSubList, map, businessUtil.getTenantCompanyName(), name);
            //上传文件至阿里云
            File fileTemp = new File(name);
            InputStream in = new FileInputStream(fileTemp);
            UploadFile2OSS oss = new UploadFile2OSS(aliyunOSSConfig);
            result = "http://tuotuo-dev.oss-cn-beijing.aliyuncs.com/take-record/" + "level_" + fileName + ".pdf";
            oss.uploadPublic(aliyunOSSConfig.getBucketName(), "take-record/" + "level_" + fileName + ".pdf", in);
            oss.closeConnect();
            in.close();
            //删除本地文件
            if (fileTemp.exists()) {
                fileTemp.delete();
            }
        } catch (IOException e) {
            e.printStackTrace();
            return ResponseData.andaError(ReturnCode.RETURN_ERROR.code, "送车单生成失败");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return ResponseData.andaSuccess(ReturnCode.RETURN_SUCCESS, result, "送车单生成成功");
    }



    @AnonymousGetMapping("/excel/download")
    public void download(HttpServletResponse response) throws Exception {
        EasyExcelUtil.export2Web(response, "测试", "模板", DownloadData.class, new ArrayList());
    }
}
